import Cesium from '../../Ces/Cesium';
import DistanceLegendViewModel from './ViewModels/DistanceLegendViewModel.js';
import NavigationViewModel from './ViewModels/NavigationViewModel.js';

// 假设 Viewer 类型，如果有实际定义请替换为准确类型
interface Viewer {
    cesiumWidget?: any;
    options?: any;
}

// 假设 CesiumWidget 类型，如果有实际定义请替换为准确类型
interface CesiumWidget {
    container: HTMLElement;
    cesiumNavigation?: CesiumNavigation;
}

/**
 * @alias CesiumNavigation
 * @constructor
 *
 * @param {Viewer|CesiumWidget} viewerCesiumWidget The Viewer or CesiumWidget instance
 */
class CesiumNavigation {
    distanceLegendViewModel: DistanceLegendViewModel | undefined;
    navigationViewModel: NavigationViewModel | undefined;
    navigationDiv: HTMLElement | undefined;
    distanceLegendDiv: HTMLElement | undefined;
    terria: Viewer | CesiumWidget | any;
    container: HTMLElement | undefined;
    private _onDestroyListeners: (() => void)[];
    private _navigationLocked: boolean;

    constructor(viewerCesiumWidget: Viewer | CesiumWidget) {
        this.initialize(viewerCesiumWidget);
        this._onDestroyListeners = [];
        this._navigationLocked = false;
    }

    setNavigationLocked(locked: boolean): void {
        this._navigationLocked = locked;
        if (this.navigationViewModel) {
            this.navigationViewModel.setNavigationLocked(this._navigationLocked);
        }
    }

    getNavigationLocked(): boolean {
        return this._navigationLocked;
    }

    destroy(): void {
        if (this.navigationViewModel) {
            this.navigationViewModel.destroy();
        }
        if (this.distanceLegendViewModel) {
            this.distanceLegendViewModel.destroy();
        }

        if (this.navigationDiv) {
            this.navigationDiv.parentNode?.removeChild(this.navigationDiv);
        }
        delete this.navigationDiv;

        if (this.distanceLegendDiv) {
            this.distanceLegendDiv.parentNode?.removeChild(this.distanceLegendDiv);
        }
        delete this.distanceLegendDiv;

        if (this.container) {
            this.container.parentNode?.removeChild(this.container);
        }
        delete this.container;

        for (const callback of this._onDestroyListeners) {
            callback();
        }
    }

    addOnDestroyListener(callback: () => void): void {
        if (typeof callback === "function") {
            this._onDestroyListeners.push(callback);
        }
    }

    private initialize(viewerCesiumWidget: Viewer | CesiumWidget, options: any = {}): void {
        if (!Cesium.defined(viewerCesiumWidget)) {
            throw new Cesium.DeveloperError('CesiumWidget or Viewer is required.');
        }

        const cesiumWidget = Cesium.defined((viewerCesiumWidget as Viewer).cesiumWidget)? (viewerCesiumWidget as Viewer).cesiumWidget : viewerCesiumWidget as CesiumWidget;

        const container = document.createElement('div');
        container.className = 'cesium-widget-cesiumNavigationContainer';
        cesiumWidget.container.appendChild(container);

        this.terria = viewerCesiumWidget;
        this.terria.options = Cesium.defined(options)? options : {};
        this.terria.afterWidgetChanged = new Cesium.Event();
        this.terria.beforeWidgetChanged = new Cesium.Event();
        this.container = container;

        // Register custom Knockout.js bindings.  If you're not using the TerriaJS user interface, you can remove this.
        // registerKnockoutBindings();

        if (!Cesium.defined(this.terria.options.enableDistanceLegend) || this.terria.options.enableDistanceLegend) {
            this.distanceLegendDiv = document.createElement('div');
            container.appendChild(this.distanceLegendDiv);
            this.distanceLegendDiv.setAttribute("id", "distanceLegendDiv");
            this.distanceLegendViewModel = DistanceLegendViewModel.create({
                container: this.distanceLegendDiv,
                terria: this.terria,
                //@ts-ignore
                mapElement: container,
                enableDistanceLegend: true
            });
        }

        if ((!Cesium.defined(this.terria.options.enableZoomControls) || this.terria.options.enableZoomControls) && (!Cesium.defined(this.terria.options.enableCompass) || this.terria.options.enableCompass)) {
            this.navigationDiv = document.createElement('div');
            this.navigationDiv.setAttribute("id", "navigationDiv");
            container.appendChild(this.navigationDiv);
            // Create the navigation controls.
            this.navigationViewModel = NavigationViewModel.create({
                container: this.navigationDiv,
                terria: this.terria,
                enableZoomControls: true,
                enableCompass: true
            });
        } else if ((Cesium.defined(this.terria.options.enableZoomControls) &&!this.terria.options.enableZoomControls) && (!Cesium.defined(this.terria.options.enableCompass) || this.terria.options.enableCompass)) {
            this.navigationDiv = document.createElement('div');
            this.navigationDiv.setAttribute("id", "navigationDiv");
            container.appendChild(this.navigationDiv);
            // Create the navigation controls.
            this.navigationViewModel = NavigationViewModel.create({
                container: this.navigationDiv,
                terria: this.terria,
                enableZoomControls: false,
                enableCompass: true
            });
        } else if ((!Cesium.defined(this.terria.options.enableZoomControls) || this.terria.options.enableZoomControls) && (Cesium.defined(this.terria.options.enableCompass) &&!this.terria.options.enableCompass)) {
            this.navigationDiv = document.createElement('div');
            this.navigationDiv.setAttribute("id", "navigationDiv");
            container.appendChild(this.navigationDiv);
            // Create the navigation controls.
            this.navigationViewModel = NavigationViewModel.create({
                container: this.navigationDiv,
                terria: this.terria,
                enableZoomControls: true,
                enableCompass: false
            });
        } else if ((Cesium.defined(this.terria.options.enableZoomControls) &&!this.terria.options.enableZoomControls) && (Cesium.defined(this.terria.options.enableCompass) &&!this.terria.options.enableCompass)) {
            //this.navigationDiv.setAttribute("id", "navigationDiv");
            // container.appendChild(this.navigationDiv);
            // Create the navigation controls.
            //this.navigationViewModel = NavigationViewModel.create({
            //    container: this.navigationDiv,
            //    terria: this.terria,
            //    enableZoomControls: false,
            //    enableCompass: false
            //});
        }
    }
}

export default CesiumNavigation;
